/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include <atomic>

#include "core/属性.h"
#include "core/引擎配置.h"
#include "core/shader_binding_ID.h"

#include "底层绘图/底层绘图框架.h"
#include "场景/场景.h"
#include "物体/物体.h"
#include "窗口/窗口.h"
#include "纹理/纹理.h"
#include "材质/资产.h"
#include "材质/材质.h"
#include "文件/文件.h"

#include "系统/系统平台.h"
#include "物理/物理.h"
#include "UI/UI.h"

#include "面/面.h"
#include "数学/数学.h"
#include "动作/非线性动画条.h"





struct S_Engine {
	
	static S_UI渲染环境*   m_UIctx;
	static bool            m_资源加载线程;
	static bool            g_渲染线程;
	static std::atomic_int g_在运行线程;
	static std::map<uint64, S_Window*> g_窗口容器;

	static S_结构对象* g_场景阴影纹理布局;
	static S_结构对象* g_场景环境渲染参数布局;
	static S_结构对象* g_场景几何纹理渲染布局;
	static S_结构对象* g_光栅最终渲染参数布局;

	static S_引擎配置		g_引擎配置;
	
	
	static S_帧缓存*	g_阴影帧缓存512;
	static S_帧缓存*	g_阴影帧缓存1024;
	static S_帧缓存*	g_阴影帧缓存2048;
	static S_帧缓存*	g_阴影帧缓存4096;
	static S_帧缓存*	g_阴影帧缓存8192;

	static S_后期处理	g_后期处理;
	//static S_GPU计算*	g_后期预览调试;

	S_绘图框架* m_绘图框架;

	E_绘图API		m_API_Name;
	S_Scene*		m_当前更新场景;
	

	S_Engine();
	~S_Engine();


	void f_InitDX12();
	void f_InitVK();
	void f_CloseVK();
	
	S_设备			f_get设备(uint32 物理设备ID);
	//S_设备环境		f_get环境(uint32 物理设备ID, uint32 逻辑设备ID);

	S_设备			f_get光追设备();
	S_设备			f_get设备();
	S_设备环境		f_gen光追设备环境(uint32 逻辑设备ID);
	S_设备环境		f_gen设备环境(S_设备& 设备);
	void			f_del设备环境(S_设备环境& ctx);
	
	
	void f_asynLoop();
	void f_Close(S_设备环境& ctx);

	void f_initGPU参数内存(S_设备环境& ctx);

	static void		f_释放线程数据();
	static S_Mesh*	f_get预设图形网格();

	static void		f_记录日志(const std::string info);

private:
	S_逻辑设备	f_创建绘图设备(uint32 物理设备ID);
	static void f_释放设备数据();

	std::vector<void*>	m_绘图环境;
};


//#define DEF_记录日志( info ) S_Engine::f_记录日志( info )



S_帧渲染层* f_create帧渲染层(C_Widget管理& gm, S_Scene* scene);

S_Engine*	f_engine_创建(E_绘图API type = E_绘图API::E_Vulkan);
void		f_engine_销毁(S_Engine* engine);

void f_engine_创建3D缓存(S_设备环境& ctx, bool 启用光追);
void f_engine_销毁3D缓存(S_设备环境& ctx);

void f_engine_创建2D缓存(S_设备环境& ctx, bool 启用光追);
void f_engine_销毁2D缓存(S_设备环境& ctx);


void f_engine_初始化材质数据(S_设备环境& ctx, bool 启用光追);

void f_engine_创建光栅渲染(S_设备环境& ctx);
void f_engine_销毁光栅渲染(S_设备环境& ctx);




S_GPU参数槽 f_engine_环境渲染参数槽布局2();
S_GPU参数槽 f_engine_环境后期参数槽布局0();
S_GPU参数槽 f_engine_几何渲染参数槽布局0();
S_GPU参数槽 f_engine_最终渲染参数槽布局2();
S_GPU参数槽 f_engine_后期光影计算参数槽布局0();
S_GPU参数槽 f_engine_后期屏幕效果合成参数槽布局0();


S_灯光系统* f_engine_创建灯光系统();
void		f_engine_组织灯光阴影纹理(S_灯光系统* ls, S_物体** 灯光物体, uint32 num);


template<typename T>
void f_from模型三角网格(S_物体* obj, const T& fun) {
	auto* mesh = f_ob_getMesh(obj);
	if (mesh) {
		/*S_三角Mesh t;
		
		auto ve = mesh->f_map顶点();
		auto ie = mesh->f_map索引();

		t.m_vert = (vec3*)ve.point;
		t.m_vNum = ve.count;

		t.m_index = (uvec3*)ie.point;
		t.m_iNum = ie.count / 3;

		fun(t);*/
	}
}


template<typename T>
S_板载缓存* f_engine_GPU映射内存(S_设备环境& ctx, uint32 预分配数量 = 0) {
	return f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | E_板载缓存类型::e_着色端内存地址, sizeof(T), 预分配数量);
}


